﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MaxLeaf.Common;
using System.Data;
using MaxLeaf.DB;
namespace MaxLeaf.DAL
{
    public interface ICheckLog
    {
        bool CheckLog(ServerInfo server, System.Data.DataRowView drv);
    }

    /// <summary>
    /// checklog操作基类
    /// </summary>
    public class BaseDALBuilder : ICheckLog
    {
               
        
        public interface IDALAction
        {
            void Add(DBAccess dbOrgCon, DBAccess dbCon, string strKeyValue);
            void Update(DBAccess dbOrgCon, DBAccess dbCon, string strKeyValue);
            void Delete(DBAccess dbOrgCon, DBAccess dbCon, string strKeyValue);
            
            
        }

        private IDALAction _k3DAL = null;
        private IDALAction _webDAL = null;
        
      
        


        protected IDALAction K3DAL
        {
            set
            {
                _k3DAL = value;
                //_k3DAL.GetData += new GetDataEventHandler(DAL_GetData);
            }
        }
        protected IDALAction WebDAL
        {
            set
            {
                
                _webDAL = value;
                //_webDAL.GetData += new GetDataEventHandler(DAL_GetData);
            }
        }
        public BaseDALBuilder()
        {
            
            
        }


        public bool CheckLog(ServerInfo orgServer, System.Data.DataRowView drvLog)
        {
            LogManager.Debug(string.Format("begin CheckLog {0}", orgServer));
            //源数据是否需要分发
            if (!ValidCheckOrgData(orgServer, drvLog))
            {
                LogManager.Debug(string.Format("ValidCheckOrgData=false {0}", orgServer));
                return  true;
            }
        
            LogStatus iLogStatus = (LogStatus)CvtFunc.ToInt(drvLog[DEL.LogDEL.LogStatus]);
            LogManager.Debug(string.Format(" {0}   {1}", orgServer, iLogStatus));
            //得到唯一需要运行的数据库，如果没有就全部
            string strK3DestServerDBName = GetK3DestServerDBName(orgServer,drvLog);
            string strWebDestServerDBName = GetWebDestServerDBName(orgServer, drvLog);

            List<ServerInfo> destServers = ServerInfo.GetServers(ServerType.All, CvtFunc.ToString(drvLog[DEL.LogDEL.UpdateMode]));
            bool blnRT = true;
            foreach (ServerInfo destServer in destServers)
            {

                if (destServer.MasterDB)
                {
                    //访问主账套
                    if (strK3DestServerDBName.Length == 0 || strK3DestServerDBName.Equals(destServer.Database, StringComparison.InvariantCultureIgnoreCase))
                    {
                        DoAction(drvLog, iLogStatus, ref blnRT, orgServer, destServer);
                    }
                    if (destServer.CityDBs != null && destServer.CityDBs.Count > 0)
                    {
                        foreach (ServerInfo cityServer in ServerInfo.GetCityServers(destServer, new DBAccess(destServer).GetAllServers()))
                        {
                            //访问分账套
                            if (strK3DestServerDBName.Length == 0 || strK3DestServerDBName.Equals(cityServer.Database, StringComparison.InvariantCultureIgnoreCase))
                            {
                                DoAction(drvLog, iLogStatus, ref blnRT, orgServer, cityServer);
                            }
                        }
                    }
                }
                else
                {

                    if (strWebDestServerDBName.Length == 0 || strWebDestServerDBName.Equals(destServer.Database, StringComparison.InvariantCultureIgnoreCase))
                    {
                        DoAction(drvLog, iLogStatus, ref blnRT, orgServer, destServer);
                    }
                }
            }
            return blnRT;
        }

        protected virtual  string GetK3DestServerDBName(ServerInfo orgServer, DataRowView drvLog)
        {
            return string.Empty;
        }
        protected virtual string GetWebDestServerDBName(ServerInfo orgServer, DataRowView drvLog)
        {
            return string.Empty;
        }

        private void DoAction(System.Data.DataRowView drvLog, LogStatus iLogStatus, ref bool blnRT, ServerInfo orgServer, ServerInfo destServer)
        {
            LogManager.Debug(string.Format(" DoAction {0}   {1}", orgServer, destServer));
            //源==目标
            if (orgServer.Type == destServer.Type && orgServer.Database == destServer.Database)
            {
                return ;
            }
            
            IDALAction dal = GetDAL(destServer);

            if ((orgServer.AcctType.Equals("mary") && destServer.Type == ServerType.Web)
                ||
                (destServer.AcctType.Equals("mary") && orgServer.Type == ServerType.Web)
                )
            {
                //20111010接口需求_1, 玛丽文化总帐套.1, 现取消所有玛丽文化总帐套（mary）和网站的关联
                dal = null;
            }

            if (dal == null)
            {
                //目标不需要操作
                LogManager.Debug(string.Format(" 目标不需要操作 {0}   {1}", orgServer, destServer));
                return;
            }

            //是否需要分发当前目标
            
             
                if (!ValidCheck(orgServer, destServer, drvLog))
                {
                    LogManager.Debug(string.Format(" 不需要分发当前目标 {0}   {1}", orgServer, destServer));
                    return;
                }
            

            using (DBAccess dbOrgCon = new DBAccess(orgServer), dbCon = new DBAccess(destServer))
            {
                try
                {
                    dbCon.BeginTrans();

                    if (iLogStatus == LogStatus.Delete)
                    {
                        dal.Delete(dbOrgCon, dbCon, CvtFunc.ToString(drvLog[DEL.LogDEL.KeyValue]));
                    }
                    else if (iLogStatus == LogStatus.Add)
                    {
                        dal.Add(dbOrgCon, dbCon, CvtFunc.ToString(drvLog[DEL.LogDEL.KeyValue]));
                    }
                    else if (iLogStatus == LogStatus.Update)
                    {
                        dal.Update(dbOrgCon, dbCon, CvtFunc.ToString(drvLog[DEL.LogDEL.KeyValue]));
                    }
                    dbCon.CommitTrans();

                    if (orgServer.MasterDB)
                    {
                        //记录分发过的数据库，下次直接跳过
                        LogCompleted(dbOrgCon, destServer, drvLog);
                    }
                }
                catch (Exception ex)
                {
                    dbCon.RollbackTrans();
                    LogManager.Error(ex);
                    blnRT = false;
                }

            }

        }

        protected virtual bool ValidCheckOrgData(ServerInfo orgServer , DataRowView drvLog)
        {
             
            return true;
        }

        protected virtual bool ValidCheck(ServerInfo orgServer, ServerInfo destServer, DataRowView drvLog)
        {
            //if (orgServer.MasterDB)
            //{
            //    using (DBAccess dbOrgCon = new DBAccess(orgServer))
            //    {
            //        DataRow drCheck = dbOrgCon.GetTableDataFirstRow("mLogComplete", new Dictionary<string, object>() { { "RecID", drvLog[DEL.LogDEL.RecId] }, { "DBName", destServer.ToString() } });
            //        if (drCheck != null)
            //        {
            //            //已处理log
            //            return false;
            //        }
            //    }
            //}
            return true;
        }

        private void LogCompleted(DBAccess dbOrgCon, ServerInfo destServer, DataRowView drvLog)
        {
            string strSql = @"
            if not exists(select * from mLogComplete where RecID=@RecID  and DBName=@DBName)
            begin
            insert into mLogComplete(RecID,DBName) values(@RecID,@DBName)
            end";
            KeyValuePair<string, IDataParameter[]> kvp = dbOrgCon.CreateCondParam(new Dictionary<string, object>() { { "RecID", drvLog[DEL.LogDEL.RecId] }, { "DBName", destServer.ToString() } });
            dbOrgCon.ExecuteSql(strSql,kvp.Value);
        }
        

        

        private IDALAction GetDAL(ServerInfo server)
        {
            if (server.Type == ServerType.K3)
            {
                return _k3DAL;
            }
            else
            {
                return _webDAL;
            }
        }


    }
}
